<!doctype html>
<html lang="zh-cn">
<head>

    <meta charset="utf-8">
    <meta name="generator" content="Hugo 0.57.2" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>58帖子服务分析 | The Sky of OtsWang</title>
    <meta property="og:title" content="58帖子服务分析 - The Sky of OtsWang">
    <meta property="og:type" content="article">
        
    <meta property="article:published_time" content="2019-05-27T19:02:47&#43;08:00">
        
        
    <meta property="article:modified_time" content="2019-05-27T19:02:47&#43;08:00">
        
    <meta name="Keywords" content="golang,go语言,otswang,java,博客,python">
    <meta name="description" content="58帖子服务分析">
        
    <meta name="author" content="OtsWang">
    <meta property="og:url" content="https://otswang.gitee.io/hugo/post/design/big/">
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">

    <link rel="stylesheet" href="/hugo/css/normalize.css">
    
        <link rel="stylesheet" href="/hugo/css/prism.css">
    
    <link rel="stylesheet" href="/hugo/css/style.css">
    <script type="text/javascript" src="//cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>

    


    
    
</head>

<body>
<header id="header" class="clearfix">
    <div class="container">
        <div class="col-group">
            <div class="site-name ">
                
                    <a id="logo" href="https://otswang.gitee.io/hugo/">
                        The Sky of OtsWang
                    </a>
                
                <p class="description">擅长写HelloWorld的小小码农</p>
            </div>
            <div>
                <nav id="nav-menu" class="clearfix">
                    
                    
                    <a  href="https://otswang.gitee.io/hugo/" title="Home">Home</a>
                    
                    <a  href="https://otswang.gitee.io/hugo/tags/" title="Tags">Tags</a>
                    
                    <a  href="https://otswang.gitee.io/hugo/categories/" title="Categories">Categories</a>
                    
                    <a  href="https://otswang.gitee.io/hugo/archives/" title="Archives">Archives</a>
                    
                    <a  href="https://otswang.gitee.io/hugo/about/" title="About">About</a>
                    
                </nav>
            </div>
        </div>
    </div>
</header>


<div id="body">
    <div class="container">
        <div class="col-group">

            <div class="col-8" id="main">
                <div class="res-cons">
                    <article class="post">
                        <header>
                            <h1 class="post-title">58帖子服务分析</h1>
                        </header>
                        <date class="post-meta meta-date">
                            2019年5月27日
                        </date>
                        
                        <div class="post-meta">
                            <span>|</span>
                            
                                <span class="meta-category"><a href="https://otswang.gitee.io/hugo/categories/design">Design</a></span>
                            
                        </div>
                        
                        
                        
                        <div class="post-content">
                            <p>对58帖子服务的学习。</p>

<h2 id="背景描述">背景描述</h2>

<p>58的核心数据： 帖子（招聘，房产，二手商品等，每个品类又有不同的子类）</p>

<p>帖子的特点：</p>

<ul>
<li>各品类帖子的属性千差万别，属性会有很多，万级别</li>
<li>数据量大，百亿级别</li>
<li>每个属性都有查询需求，各组合属性上可能有组合查询的需求</li>
<li>吞吐量大，每秒数10万级别</li>
</ul>

<h2 id="初期方案">初期方案</h2>

<p>初期业务少，帖子可以设计为：<code>tiezi(tid, uid, c1, c2, c3)</code>.</p>

<p>组合查询通过索引<code>index(c1, c2), index(c1,c3), index(c2,c3)</code>。</p>

<p>当业务增长，出现更多的属性（房产，二手车等），帖子变为：`tiezi(tid, uid, c1, c2, c3, c10, c11, c12).其中，c1,c2,c3为招聘类属性，c10,c11,c12等为房产类属性。</p>

<p>此时继续增加索引以满足查询条件。但是当业务不断增加时，越来越多的属性将无法只通过新增索引来优化查询，因为增加索引也是需要成本的。</p>

<h2 id="垂直拆分">垂直拆分</h2>

<p>将不同属性的帖子进行拆分：</p>

<p><code>tiezi_zhaopin(tid, uid, c1, c2, c3)</code>与<code>tiezi_fangchan(tid, uid, c10, c11, c12)</code>。</p>

<p>表拆分也会造成各种问题，比如：</p>

<ul>
<li>tid如何规范</li>
<li>按照tid进行查询怎么办</li>
<li>按照时间查询怎么处理</li>
</ul>

<p>电商的商品表，不可能一个类目一个表的。</p>

<h2 id="58的做法">58的做法</h2>

<ol>
<li>统一帖子中心服务</li>
</ol>

<p>如何将不同品类，异构的数据统一存储起来？</p>

<ul>
<li>全品类通用属性统一存储</li>
<li>单品类特有属性，品类类型和通用属性json进行存储</li>
</ul>

<p>具体来说：</p>

<p><code>tiezi(tid, uid, time, title, cate, subcate, xxid, ext);</code>将一些通用的字段抽取出来单独存储;通过cate， subcate，xxid等定义ext的意义;通过ext来存储不同的业务线需求。</p>

<table>
<thead>
<tr>
<th>tid</th>
<th>uid</th>
<th>time</th>
<th>cateid</th>
<th>ext</th>
</tr>
</thead>

<tbody>
<tr>
<td>1</td>
<td>1</td>
<td>123</td>
<td>招聘</td>
<td>{&ldquo;job&rdquo;:&ldquo;driver&rdquo;, &ldquo;salary&rdquo;: 8000, &ldquo;location&rdquo;: &ldquo;bj&rdquo;}</td>
</tr>

<tr>
<td>2</td>
<td>1</td>
<td>345</td>
<td>二手</td>
<td>{&ldquo;type&rdquo;: &ldquo;iphone&rdquo;, &ldquo;money&rdquo;: 800}</td>
</tr>
</tbody>
</table>

<ol>
<li>统一类目属性服务</li>
</ol>

<p>每个业务有多少属性，这些属性的含义，值的约束等，耦合到帖子服务里，显然是不合理的，因此抽象出一个统一的类目、属性服务，单独来管理这些信息，而帖子的ext字段里的json里的key，使用id来表示</p>

<table>
<thead>
<tr>
<th>tid</th>
<th>uid</th>
<th>time</th>
<th>cateid</th>
<th>ext</th>
</tr>
</thead>

<tbody>
<tr>
<td>1</td>
<td>1</td>
<td>123</td>
<td>招聘</td>
<td>{&ldquo;1&rdquo;:&ldquo;driver&rdquo;, &ldquo;2&rdquo;: 8000, &ldquo;3&rdquo;: &ldquo;bj&rdquo;}</td>
</tr>

<tr>
<td>2</td>
<td>1</td>
<td>345</td>
<td>二手</td>
<td>{&ldquo;4&rdquo;: &ldquo;iphone&rdquo;, &ldquo;5&rdquo;: 800}</td>
</tr>
</tbody>
</table>

<p>备注： 帖子只保存元信息，不管业务含义。</p>

<p>类目、属性服务表如下：</p>

<table>
<thead>
<tr>
<th>key_id</th>
<th>cateId</th>
<th>sub_cateid</th>
<th>desc</th>
<th>show</th>
<th>regu</th>
<th>xx</th>
</tr>
</thead>

<tbody>
<tr>
<td>1</td>
<td>招聘</td>
<td>100</td>
<td>job</td>
<td>职位</td>
<td>32 char</td>
<td>&hellip;</td>
</tr>
</tbody>
</table>

<ol>
<li>统一检索服务</li>
</ol>

<p>外置索引，统一检索服务，是一个很常用的实践：</p>

<ul>
<li>数据库提供帖子id的正排查询需求</li>
<li>所有非帖子id的个性化检索需求，统一走外置索引</li>
</ul>

<p>元数据与索引数据的操作遵循：</p>

<ul>
<li>对帖子进行tid正排查询，直接访问帖子服务</li>
<li>对帖子进行修改，帖子服务通知检索服务，同时对索引进行修改</li>
<li>对帖子进行复杂查询，通过检索服务满足需求</li>
</ul>

<p>备注： 58使用的是自研的e-search搜索引擎</p>

<h2 id="一个总结">一个总结</h2>

<p>面对100亿数据量，1万列属性，10万吞吐量的业务需求，可以采用了元数据服务、属性服务、搜索服务来解决：</p>

<ul>
<li>一个解决存储问题</li>
<li>一个解决品类解耦问题</li>
<li>一个解决检索问题</li>
</ul>

<p>任何复杂问题的解决，都是循序渐进的。</p>

<p><img src="/hugo/src/img/design/58.png" ></p>

<p>转载自： <a href="https://mp.weixin.qq.com/s/tUmj4g0IOeA7Z-YIrKhM9g">https://mp.weixin.qq.com/s/tUmj4g0IOeA7Z-YIrKhM9g</a></p>
                        </div>

                        


                        

<div class="post-archive">
    <h2>See Also</h2>
    <ul class="listing">
        
        <li><a href="/hugo/post/other/linyuqudong/">驱动领域设计学习</a></li>
        
    </ul>
</div>


                        <div class="post-meta meta-tags">
                            
                            <ul class="clearfix">
                                
                                <li><a href="https://otswang.gitee.io/hugo/tags/%E8%AE%BE%E8%AE%A1">设计</a></li>
                                
                            </ul>
                            
                        </div>
                    </article>
                    
    

    
    
                </div>
            </div>
            <div id="secondary">

    <section class="widget">
        <form id="search" action="//www.google.com/search" method="get" accept-charset="utf-8" target="_blank" _lpchecked="1">
      
      <input type="text" name="q" maxlength="20" placeholder="Search">
      <input type="hidden" name="sitesearch" value="https://otswang.gitee.io/hugo/">
      <button type="submit" class="submit icon-search"></button>
</form>
    </section>

    
    <div class="clear">
        <div class="toc-article">
            <div class="toc-title">文章目录</dixsv>
            <nav id="TableOfContents">
<ul>
<li>
<ul>
<li><a href="#背景描述">背景描述</a></li>
<li><a href="#初期方案">初期方案</a></li>
<li><a href="#垂直拆分">垂直拆分</a></li>
<li><a href="#58的做法">58的做法</a></li>
<li><a href="#一个总结">一个总结</a></li>
</ul></li>
</ul>
</nav>
        </div>
    </div>
    

</div>
        </div>
    </div>
</div>
<footer id="footer">
    <div class="container">
        &copy; 2020 <a href="https://otswang.gitee.io/hugo/">The Sky of OtsWang By OtsWang</a>.
        Powered by <a rel="nofollow noreferer noopener" href="https://gohugo.io" target="_blank">Hugo</a>.
        <a href="https://www.flysnow.org/" target="_blank">Theme</a> based on <a href="https://github.com/Dudiao137/maupassant-hugo" target="_blank">maupassant-ots</a>.
        
    </div>
</footer>


    <script type="text/javascript">
    
    (function(){
        $("pre code").parent().addClass("line-numbers")
    }())

    window.MathJax = {
        tex2jax: {
            inlineMath: [ ['$','$'] ],
            processEscapes: true
        }
    };
    </script>
    <script type="text/javascript" src="/hugo/js/prism.js" async="true"></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML' async></script>

<a id="rocket" href="#top"></a>
<script type="text/javascript" src="/hugo/js/totop.js?v=0.0.0" async=""></script>







 
 <script src="https://mermaidjs.github.io/scripts/mermaid.min.js"></script>
 <script>
       mermaid.initialize({ startOnLoad: true });
 </script>
</body>
</html>
